import 'package:flutter/material.dart';
import 'package:new_trend/widgets/timer_text.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'dart:io';
import 'dart:async';
import 'package:flutter_sound/flutter_sound.dart';

class RecorderScreen extends StatefulWidget {
  @override
  _RecorderScreenState createState() => _RecorderScreenState();
}

class _RecorderScreenState extends State<RecorderScreen> {
  Stopwatch stopwatch = new Stopwatch();
  bool _isRecording = false;
  bool _isPlaying = false;
  FlutterSound flutterSound;
  StreamController<String> overlayController = StreamController.broadcast();
  StreamSubscription overlayListener;

  @override
  void initState() {
    super.initState();
    flutterSound = FlutterSound();
    flutterSound.setSubscriptionDuration(0.01);
  }

  @override
  void dispose() {
    super.dispose();
    overlayController.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        color: Colors.orangeAccent.withOpacity(0.2),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            buildRecordingStatus(),
            buildTimerText(),
            buildButtonRow(context),
          ],
        ),
      ),
    );
  }

  void stopButtonPressed(BuildContext context) {
    setState(() {
      stopwatch
        ..stop()
        ..reset();
    });
    _isRecording = false;
    stopRecorder();
    showOverlay(context);
  }

  void recordButtonPressed() {
    setState(() {
      if (!stopwatch.isRunning) {
        stopwatch.start();
        _isRecording = true;
        startRecorder();
      }
    });
  }

  Widget buildOverlayButton(String text, Color color, VoidCallback callback) {
    const double redius = 12.0;
    return GestureDetector(
      onTap: callback,
      child: Container(
        padding: EdgeInsets.all(16.0),
        color: color,
        child: Center(
          child: Text(
            text,
            style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 36.0,
              color: Colors.white,
            ),
          ),
        ),
      ),
    );
  }

  Widget buildTimerText() {
    return Container(
        height: 200.0,
        child: new Center(
          child: new TimerText(stopwatch: stopwatch),
        ));
  }

  Widget buildRecordingStatus() {
    return Container(
        height: 100.0,
        width: 100.0,
        child: stopwatch.isRunning
            ? Center(
          child: SpinKitWave(
              color: Colors.black87.withOpacity(0.7),
              type: SpinKitWaveType.start),
        )
            : Image.asset("assets/recorder.png"));
  }

  Widget buildButtonRow(BuildContext context) {
    return Row(children: <Widget>[
      buildButton(()=>stopButtonPressed(context), Colors.redAccent, context, Icons.stop),
      buildButton(recordButtonPressed, Colors.blueAccent, context,
          stopwatch.isRunning ? Icons.pause : Icons.play_arrow),
    ]);
  }

  Widget buildButton(
      VoidCallback callback, Color color, BuildContext context, IconData icon) {
    Size size = MediaQuery.of(context).size;
    return Container(
        width: size.width * 0.5,
        alignment: Alignment.center,
        child: RaisedButton(
          elevation: 0.0,
          shape: new RoundedRectangleBorder(
              borderRadius: new BorderRadius.circular(36.0)),
          color: color,
          onPressed: callback,
          child: Container(
            width: size.width * 0.5 - 80.0,
            height: MediaQuery.of(context).size.width * 0.15,
            child: Icon(
              icon,
              color: Colors.white,
              size: 32.0,
            ),
          ),
        ));
  }

  showOverlay(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    OverlayState overlayState = Overlay.of(context);
    OverlayEntry overlayEntry = OverlayEntry(builder: (context) {
      return Scaffold(
        backgroundColor: Colors.black.withOpacity(0.5),
        body: Center(
          child: Material(
            child: Container(
              width: size.width / 1.4,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  buildOverlayButton('PLAY', Colors.lightBlueAccent, this.startPlayer),
                  buildOverlayButton('PLUSE', Colors.pinkAccent, this.pausePlayer),
                  buildOverlayButton(
                      'STOP', Colors.lightGreen.withOpacity(0.9), this.stopPlayer),
                  buildOverlayButton(
                      'UPLOAD', Colors.deepPurpleAccent.withOpacity(0.8), null),
                  buildOverlayButton(
                      'BACK', Colors.grey.withOpacity(0.5), this.removeOverlay)
                ],
              ),
            ),
          ),
        ),
      );
    });
    overlayState.insert(overlayEntry);
    overlayListener = overlayController.stream.listen((data) {
      overlayEntry.remove();
      overlayListener.cancel();
      //TODO: handle multiple listen exception
    });
  }

  void removeOverlay() {
    overlayController.add("close");
  }

  void startRecorder() async {
    try {
      String path = await flutterSound.startRecorder(null);
      print('startRecorder: $path');

      this.setState(() {
        this._isRecording = true;
      });
    } catch (err) {
      print('startRecorder error: $err');
    }
  }

  void stopRecorder() async {
    try {
      String result = await flutterSound.stopRecorder();
      print('stopRecorder: $result');

      this.setState(() {
        this._isRecording = false;
      });
    } catch (err) {
      print('stopRecorder error: $err');
    }
  }

  void startPlayer() async {
    String path = await flutterSound.startPlayer(null);
    await flutterSound.setVolume(1.0);
    print('startPlayer: $path');

    try {} catch (err) {
      print('error: $err');
    }
  }

  void stopPlayer() async {
    try {
      String result = await flutterSound.stopPlayer();
      print('stopPlayer: $result');

      this.setState(() {
        this._isPlaying = false;
      });
    } catch (err) {
      print('error: $err');
    }
  }

  void pausePlayer() async {
    String result = await flutterSound.pausePlayer();
    print('pausePlayer: $result');
  }

  void resumePlayer() async {
    String result = await flutterSound.resumePlayer();
    print('resumePlayer: $result');
  }

  void seekToPlayer(int milliSecs) async {
    int secs = Platform.isIOS ? milliSecs / 1000 : milliSecs;

    String result = await flutterSound.seekToPlayer(secs);
    print('seekToPlayer: $result');
  }
}

